<?php

/**
 * odb class 提供操作数据库的封装model，快速进行数据库操作
 * 
 * query($string)
 * 执行一条sql查询语句，返回执行结果
 * 
 * add($tab,$data)
 * 插入一条记录，参数为表名，字段和数据的键值对关联数组
 * 
 * adds($tab,$fields,$data)
 * 插入多条记录，参数为表名，字段集合（普通数组），数据（二维数组，第二维的数据顺序应该与字段顺序一致）
 * 
 * add_only($tab,$data,$where=array(),$isAnd=false)
 * 插入某字段唯一的记录，如果已存在，则返回array("code"=>0,result=>array()),查询到的已有值。
 * 参数：tab表名；data要插入的数据；where普通数组，保持唯一性的字段名称集合；isAnd布尔值，false将使where用or连接，只要where中有一个存在则不能插入新数据，true则是where中所有的字段值均存在才不插入。
 * 
 * delete_one($tab,$where)
 * 删除一条记录；参数：tab表名，where：要刪除的项的where限定，关联数组，字段和值
 * 
 * update($tab,$where,$data)
 * 修改一条记录，tab表名；where关联数组，要删除的项；data数据，键值对关联数组
 * 
 * get($tab,$select= '*',$where = NULL,$limit=NULL)
 * 获取数据。tab表名；select需要的字段 字符串形式；where限定查询记录，字符串和关联数组；limit分页限定，普通数组，第一个参数为起始位置，第二个为数量。
 * 返回查询到的的数据集合。
 * 
 */




class Odb extends CI_Model
{
	public function __construct()
	{
		parent::__construct();
		$this->load->database();
	}
	protected $ret;


	/* 
 query  传入数据库查询字符串，直接查询。
 @params [string] $querystr [数据库查询字符串]
 @return [array] 查询到的结果，转化为的array
 */
	public function query($queryStr)
	{

		$da = $this->db->query($queryStr);
		$this->ret = $da;
		return $this->ret;
	}





	/**
	 * [add 往数据表中增加一条记录]
	 * @param [string] $tab  [数据表名称]
	 * @param [object array] $data [对象或关联数组，插入表中的新记录的值]
	 * @return   [<返回插入行的id值>]
	 */
	public function add($tab, $data)
	{

		$this->db->insert($tab, $data);
		$this->ret = $this->db->insert_id();
		return $this->ret;
	}



	/**
	 * @example: adds('tabName',array('a','b','c'),array(array('v1','v2','v3'),array('v1','v2','v3')))
	 * @description: adds函数用于拼接一次插入多条数据进入数据库的sql语句并执行它实现插入多条数据。只在mysql数据库可以。
	 * @param {string} [tab] [要插入的数据表]
	 * @param {array} [fields] [字段名列表，普通数组]
	 * @param {array} [data] [要插入的数据，二维普通数组，第二维的数组的数据顺序应该与fields顺序相对应]
	 * @return: {boolean} --- example: true
	 */
	public function adds($tab, $fields, $data)
	{
		$insertValues = array();
		foreach ($data as $item) {
			$insertValues[] =  "('" . implode("','", $item) . "')"; //循环每一条记录拼接查询字符串
		}
		$insertValuesStirng = implode(",", $insertValues); //每一条字符串拼接成一条语句
		$fieldsStr = "`" . implode("`,`", $fields) . "`"; //拼接字段名
		$queryStr = "INSERT INTO `" . $tab . "`(" . $fieldsStr . ") VALUES " . $insertValuesStirng; //拼接sql语句
		$ret = $this->db->query($queryStr); //执行sql语句，查询
		return $ret;
	}









	/**
	 * [add_only 往数据表中增加一条唯一的记录，
	 * 以$where字段的值为唯一，如果已存在，则不插入数据，返回0和查询到的数据，如果插入成功返回id。
	 * 如果不提供where参数，则行为与add一致，均会添加一条记录进入数据库]
	 * @param [string] $tab  [数据表名称]
	 * @param [object array] $data [对象或关联数组，插入表中的新记录的值]
	 * @param [array] $where [普通数组，保持唯一性的字段名称集合，只要这些字段中有一个已存在相同的值，就不能插入]
	 * @param [boolean] $isAnd [$isAnd=false，是否是and条件，默认是false，使用or_where语句，为true则使用where语句。]
	 * @return {number | array}  [<返回插入行的id值>]
	 */

	public function add_only($tab, $data, $where = array(), $isAnd = false)
	{

		// 查询是否已存在以某些字段值为唯一的记录
		// $this->db->select($where[0]);
		$where2 = array();
		if (empty($where)) { //如果where是空，则直接插入数据，不做唯一性判断

			$result = array();
		} else { //where不为空的情况

			if($where === '*'){//如果where为*，则将判断data中的所有字段
				$where = array();
				foreach($data as $key => $val){
					$where[] = $key;
				}
			}
			if(!is_array($where)){
				// where必须是数组，如果不是则直接返回负一。
				return -1;
			}

			foreach ($where as $item) {
				if (isset($data[$item])) {
					$where2[$item] = $data[$item];
				}
			}
			// 是and条件还是or条件,默认是or条件
			if ($isAnd) {
				$this->db->where($where2);
			} else {
				$this->db->or_where($where2);
			}

			$result = $this->db->get($tab)->result_array();
		}

		if (count($result) === 0) {
			$this->db->insert($tab, $data);
			$this->ret = $this->db->insert_id();
			return $this->ret;
		} else {
			return array('code' => 0, 'data' => $result);
		}
	}





	/**
	 * [delete_one 删除一条记录]
	 * @param  [string array] $tab   [字符串和普通数组]
	 * @param  [array] $where [关联数组，键为字段名,对应where的记录才能删除]
	 * @return [boolean]        [ci执行delete后的返回值]
	 */
	public function delete_one($tab, $where)
	{

		$this->ret = $this->db->delete($tab, $where);
		return $this->ret;
	}

	/**
	 * [delete_all del表中所有记录]
	 * @param  [string] $tab [数据表名]
	 * @return [boolean]      [ci执行emty_table后的返回值]
	 */
	public function delete_all($tab)
	{

		$ret = $this->db->empty_table($tab);
		return $this->ret;
	}

	/**
	 * [update 修改一条记录]
	 * @param  [string] $tab   [数据表名]
	 * @param  [string array] $where [sql的where语句字符串，或键值对数组]
	 * @param  [array] $data  [关联数组，需要修改的字段及其值]
	 * @return [int]        [受影响的行数]
	 */
	public function update($tab, $where, $data)
	{

		$this->db->where($where);
		$this->db->update($tab, $data);
		$this->ret = $this->db->affected_rows();
		return $this->ret;
	}

	/**
	 * [get 查询数据]
	 * @param  [string] $tab   [表名]
	 * @param  [string] $select [select语句，规定需要查询的字段。纯字符串]
	 * @param  [string array] $where [where字符串或者关联数组]
	 * @param  [array] $limit [普通数组，0为限制量，1为偏移量]
	 * @return [array]        [查询结果关联数组]
	 */
	public function get($tab, $select = '*', $where = NULL, $limit = NULL)
	{

		$this->db->select($select);

		if ($where) {
			$this->db->where($where);
		}
		if ($limit) {
			// $limit array 两个值分别为限制量和偏移量。
			$this->db->limit($limit[0], $limit[1]);
		}
		$query = $this->db->get($tab);

		$this->ret = $query->result_array();

		return $this->ret;
	}

	/* 
	 num_rows
	 @return 返回最近一次调用后的结果的number，如果返回的是数字则看数字长度，数组则有多少项元素*/
	public function num_rows()
	{
		return count($this->ret);
		// echo count($this->ret);
	}

	/**
	 * [print_db 打印ret变量，每一次操作的返回值同时也保存在ret中，可以使用本函数打印]
	 * @return [type] [description]
	 */
	public function print_db()
	{
		echo json_encode($this->ret);
	}
}
